package io.renren.modules.crud.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.mail.MailUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tencent.common.pojo.Result;
import com.tencent.common.pojo.StatusCode;
import io.renren.common.utils.ContractDynamicParam;
import io.renren.common.utils.GeneratePdfUtil;
import io.renren.modules.crud.dao.*;
import io.renren.modules.crud.entity.*;
import io.renren.modules.crud.enums.EnumType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;


import io.renren.modules.crud.service.BorrowerService;


@Service("borrowerService")
public class BorrowerServiceImpl extends ServiceImpl<BorrowerDao, BorrowerEntity> implements BorrowerService {

    @Autowired
    InformationDao informationDao;
    @Autowired
    UsersDao usersDao;
    @Autowired
    ProductDao productDao;
    @Autowired
    BorrowerDao borrowerDao;
    @Autowired
    RepaymentDao repaymentDao;
    @Autowired
    BankcardDao bankcardDao;
    @Autowired
    ContractDao contractDao;

    private final String TEMPLATES_PATH = "D:\\专六\\拉取git代码\\vast-finance\\vast_service\\vast_service_backstages\\src\\main\\resources\\static\\";
    private final String CONTRACT_PATH = "C:\\Users\\LENOVO\\Desktop\\";

    public PageUtils queryPage(Map<String, Object> params) {
        IPage<BorrowerEntity> page = this.page(
                new Query<BorrowerEntity>().getPage(params),
                new QueryWrapper<BorrowerEntity>()
        );

        return new PageUtils(page);
    }

    public void examination(Integer borrowId, Integer infoStatus) {
        // 借款表实体类
        BorrowerEntity borrowerEntity = borrowerDao.selectById(borrowId);
        // 基本信息实体类
        InformationEntity informationEntity = informationDao.selectById(borrowerEntity.getInfoId());
        // 还款表
        RepaymentEntity repaymentEntity = repaymentDao.selectById(borrowId);
        // 状态等于1 发送pdf文件
        if (infoStatus == 1) {
            //添加贷款信息同时生成还款计划表信息
            generateInfo(borrowerEntity);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String format = simpleDateFormat.format(new Date());
            //通过邮件发送pdf
            UsersEntity usersEntity = usersDao.selectById(borrowerEntity.getUserId());
            ProductEntity productEntity = productDao.selectById(borrowerEntity.getProductId());
            // 模板数据
            HashMap<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("borrower",usersEntity.getNickName());
            paramMap.put("lender", productEntity.getCompanyName());
            paramMap.put("guarantor", informationEntity.getContactName());
            paramMap.put("create_date", format);
            paramMap.put("real_name", productEntity.getCompanyName());
            paramMap.put("card_id", usersEntity.getIdentityId());
            paramMap.put("address", informationEntity.getAddress());
            paramMap.put("repayment_date", format);
            paramMap.put("repayment_amount", borrowerEntity.getPrice());
            paramMap.put("interest_rate", borrowerEntity.getAnnual());
            paramMap.put("Interest", repaymentEntity.getAccrual());
            // 生成PDF
            ContractDynamicParam param = new ContractDynamicParam(TEMPLATES_PATH, "052012085952.ftl", CONTRACT_PATH, "贷款合同.pdf", paramMap);
            try {
                GeneratePdfUtil.GenerateContract(param);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("====生成PDF合同成功====");
            // 发送邮件
            MailUtil.send(usersEntity.getEmail(), "广大金融", "<h1>邮件来自广大金融</h1>", true, FileUtil.file("C:\\Users\\LENOVO\\Desktop\\贷款合同.pdf"));

            ContractEntity contractEntity = new ContractEntity();
            contractEntity.setBorrower(usersEntity.getNickName());
            contractEntity.setLender(productEntity.getCompanyName());
            contractEntity.setGuarantor(informationEntity.getContactName());
            try {
                Date parse = simpleDateFormat.parse(format);
                contractEntity.setCreateDate(parse);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            contractEntity.setRealName(usersEntity.getNickName());
            BankcardEntity bankcardEntity = bankcardDao.selectById(usersEntity.getCardId());
            contractEntity.setCardId(bankcardEntity.getIdentityId());
            contractEntity.setAddress(informationEntity.getAddress());
            contractEntity.setUserId(usersEntity.getUserId());
            contractEntity.setProductId(productEntity.getProductId());
            contractDao.insert(contractEntity);
        }
        borrowerEntity.setStates(1);
        QueryWrapper<BorrowerEntity> borrowerEntityQueryWrapper = new QueryWrapper<BorrowerEntity>();
        borrowerEntityQueryWrapper.eq("borrow_id",borrowId);
        borrowerDao.update(borrowerEntity,borrowerEntityQueryWrapper);
        try {
            Date parse = simpleDateFormat.parse(format);
            contractEntity.setCreateDate(parse);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        contractEntity.setRealName(usersEntity.getNickName());
        BankcardEntity bankcardEntity = bankcardDao.selectById(usersEntity.getCardId());
        contractEntity.setCardId(bankcardEntity.getIdentityId());
        contractEntity.setAddress(informationEntity.getAddress());
        contractEntity.setUserId(usersEntity.getUserId());
        contractEntity.setProductId(productEntity.getProductId());
        contractDao.insert(contractEntity);
    }

    @Override
    public Result computer(BorrowerEntity borrowerEntity) {

        HashMap<String, Object> map = new HashMap<>();

        List<HashMap<String,Object>> list = new ArrayList<>();

        // 判断是否使用优惠券
        if (borrowerEntity.getStates() != null && !borrowerEntity.getStates().equals("")) {
            borrowerEntity.setPrice(borrowerEntity.getPrice()-borrowerEntity.getStates());
        }

        // 首期
        map.put("firstPhase",getDate());

        double sumPrice = 0; // 还款总额
        double invest = borrowerEntity.getPrice();     //贷款本金
        double yearRate = 0.234;   //年利率
        double monthRate = yearRate/12;   //月利率

//      int year = 15;     //还款年数
        int month = 0;
        if (borrowerEntity.getLoanperiods().length() == 4) {
            month = Integer.parseInt(borrowerEntity.getLoanperiods().substring(0,2));  //还款月数
        }else{
            month = Integer.parseInt(borrowerEntity.getLoanperiods().substring(0,1));  //还款月数
        }

        // 每月本息金额  = (本金×月利率×(1＋月利率)＾还款月数)÷ ((1＋月利率)＾还款月数-1))
        double monthIncome = (invest* monthRate * Math.pow(1+monthRate,month))/(Math.pow(1+monthRate,month)-1);
        // 应还
        map.put("should",twoDecimalPlaces(monthIncome));

        // 每月利息  = 剩余本金 x 贷款月利率
        double monthInterest = 0;
        double capital = invest;
        double tmpCapital = 0;
        double totalInterest = 0;
        // 每月本金 = 本金×月利率×(1+月利率)^(还款月序号-1)÷((1+月利率)^还款月数-1))
        double monthCapital = 0;
        for(int i=1;i<month+1;i++){

            HashMap<String, Object> mapc = new HashMap<>();

            monthCapital = (invest* monthRate * (Math.pow((1+monthRate),i-1)))/(Math.pow(1+monthRate,month)-1);
            sumPrice=sumPrice+monthCapital;

            capital = capital - tmpCapital;
            monthInterest = capital * monthRate;
            tmpCapital = (invest* monthRate * (Math.pow((1+monthRate),i-1)))/(Math.pow(1+monthRate,month)-1);
            sumPrice = sumPrice+monthInterest;
            totalInterest = totalInterest + monthInterest;

            // 本金
            mapc.put("monthCapital",twoDecimalPlaces(monthCapital));
            // 利息
            mapc.put("monthInterest",twoDecimalPlaces(monthInterest));
            // 还款
            mapc.put("monthIncome",twoDecimalPlaces(monthIncome));

            list.add(mapc);

        }
        // 总综合利息
        map.put("sumInterest",twoDecimalPlaces(totalInterest));
        // 还款总额
        map.put("sumPrice",twoDecimalPlaces(sumPrice));

        List<HashMap<String,Object>> mapList = repaymentPlan(list);
        map.put("plan",mapList);
        return new Result(StatusCode.OK,"生成还款计划成功",true,map);
    }

    public void generateInfo(BorrowerEntity  borrower){
        //添加贷款信息同时生成还款计划表信息
        //1.判断贷款规则
        String str =  borrower.getLoanperiods().substring(0, 1);
        Integer num = Integer.valueOf(str);
        if(EnumType.ONE.getEnuTypeName().equals( borrower.getRepaymentType())){
            //等额本息
            double invest = borrower.getPrice();     //贷款本金
            double yearRate =borrower.getAnnual()/100;   //年利率
            double monthRate = yearRate / 12;   //月利率

//             int year = 15;     //还款年数
            int month = num;  //还款月数

            // 每月本金 = 本金×月利率×(1+月利率)^(还款月序号-1)÷((1+月利率)^还款月数-1))
            double monthCapital = 0;
            // 每月利息  = 剩余本金 x 贷款月利率
            double monthInterest = 0;
            double capital = invest;
            double tmpCapital = 0;
            double totalInterest = 0;
            Date time=null;
            for (int i = 1; i < month + 1; i++) {
                RepaymentEntity repaymentEntity = new RepaymentEntity();
                //添加时间
                if(i==1){
                    time=borrower.getStartTime();
                    repaymentEntity.setRepayTime(time);
                }
                monthCapital = (invest * monthRate * (Math.pow((1 + monthRate), i - 1))) / (Math.pow(1 + monthRate, month) - 1);
                capital = capital - tmpCapital;
                monthInterest = capital * monthRate;
                tmpCapital = (invest * monthRate * (Math.pow((1 + monthRate), i - 1))) / (Math.pow(1 + monthRate, month) - 1);
                System.out.println("第" + i + "月利息： " + monthInterest);
                totalInterest = totalInterest + monthInterest;
                System.out.println("第" + i + "月本金： " + monthCapital);
                //添加
                Calendar rightNow = Calendar.getInstance();
                rightNow.setTime(time);
                rightNow.add(Calendar.MONTH,1);
                time = rightNow.getTime();
                repaymentEntity.setRepayTime(time);
                //本金
                repaymentEntity.setCapital(monthCapital);
                //利息
                repaymentEntity.setAccrual(monthInterest);
                repaymentEntity.setBorrowId(borrower.getBorrowId());
                repaymentEntity.setPeriods(i);
                repaymentDao.insert(repaymentEntity);
            }
        }



        if(EnumType.TWO.getEnuTypeName().equals( borrower.getRepaymentType())){
            //等额本金
        }
        if(EnumType.THREE.getEnuTypeName().equals(borrower.getRepaymentType())){
            //每月还息一次还本
            //计算每月利息
            Double price= borrower.getPrice()*(borrower.getAnnual()/100/12);
            Date time=null;
            for (int i=1;i<=num;i++){
                RepaymentEntity repaymentEntity = new RepaymentEntity();
                if(i==1){
//                        Date NowTime= borrower.getStartTime();
//                        Calendar rightNow = Calendar.getInstance();
//                        rightNow.setTime(NowTime);
//                        rightNow.add(Calendar.MONTH,1);
//                        time = rightNow.getTime();
                    time=borrower.getStartTime();
                    repaymentEntity.setRepayTime(time);
                }
                if(i<=num-1){
                    repaymentEntity.setCapital(0.0);
                }
                if(i==num){
                    repaymentEntity.setCapital(Double.valueOf(borrower.getPrice()));
                }
                Calendar rightNow = Calendar.getInstance();
                rightNow.setTime(time);
                rightNow.add(Calendar.MONTH,1);
                time = rightNow.getTime();
                repaymentEntity.setRepayTime(time);
                repaymentEntity.setAccrual(price);
                repaymentEntity.setBorrowId(borrower.getBorrowId());
                repaymentEntity.setPeriods(i);
                repaymentDao.insert(repaymentEntity);
            }
        }

        if(EnumType.FOUR.getEnuTypeName().equals(borrower.getRepaymentType())){
            //一次还本还息
        }
    }

    /**
     * 获取每月本息金额
     * 计算方式
     * 每月本息金额  = (本金×月利率×(1＋月利率)＾还款月数)÷ ((1＋月利率)＾还款月数-1))
     * @param invest  本金
     * @param yearRate 年利率
     * @param month   还款月
     * @return 每月本息金额
     */
    public double getMonthIncome ( double invest, double yearRate, int month){
        double monthRate = yearRate / 12;   //月利率
        double monthIncome = (invest * monthRate * Math.pow(1 + monthRate, month)) / (Math.pow(1 + monthRate, month) - 1);
        return monthIncome;
    }

    // 获取首期时间

    public String getDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("MM月dd号");
        Date date = new Date();
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(date);
        rightNow.add(Calendar.MONTH,1);
        Date time = rightNow.getTime();
        String format = sdf.format(time);
        return format;
    }

    /**
     * 获取还款计划
     * @return
     */
    public List<HashMap<String,Object>> repaymentPlan(List<HashMap<String,Object>> list){

        SimpleDateFormat sdf = new SimpleDateFormat("MM月dd号");
        Date date = new Date();
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(date);

//        int i = 1;

        for (HashMap<String, Object> map : list) {
            rightNow.add(Calendar.MONTH,1);
            Date time = rightNow.getTime();
            String format = sdf.format(time);
            map.put("repayment",format);
//            i++;
        }
        return list;
    }

    public Double twoDecimalPlaces(Double d){
        String  str = String.format("%.2f",d);
        return Double.parseDouble(str);
    }

    public static void main(String[] args) {
        double one = 5.864;
        String  str = String.format("%.2f",one);
        double four = Double.parseDouble(str);
        System.out.println(four);
    }

}